package com.planw.beetl.utils;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.StringUtils;

public class StrUtil {

  private static String[] validStr = new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
      "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C",
      "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
      "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "_", ".",};

  private static char[][] validChars = new char[validStr.length][];

  static {
    for (int i = 0; i < validStr.length; i++) {
      validChars[i] = validStr[i].toCharArray();
    }
  }

  public static boolean searchCharSequence(String str, String search) {

    if (StringUtils.equals(search, "*")) {
      return true;
    }
    AtomicInteger postion = new AtomicInteger(0);
    search = StringUtils.lowerCase(search);
    str = StringUtils.lowerCase(str);
    String finalStr = str;
    search.chars().forEach(ch -> {
      if (postion.intValue() != -1) {
        postion.set(finalStr.indexOf(ch, postion.get()));
      }
    });

    return postion.intValue() != -1;
  }

  public static boolean containAny(String str, String... searchStr) {

    for (String search : searchStr) {
      if (
          (search != null && !search.trim().isEmpty())
              && str.contains(search)
      ) {
        return true;
      }
    }
    return false;
  }

  public static String findBeetlSqlVarSubStr(String text, int column, BeetlSqlConst beetlSqlConst) {

    if (text == null || text.trim().isEmpty()) {
      return "";
    }
    boolean isBeetlSqlContent = containAny(text, beetlSqlConst.DELIMITER_STATEMENT_START,
        beetlSqlConst.DELIMITER_PLACEHOLDER_START, beetlSqlConst.DELIMITER_PLACEHOLDER_START2);
    if (!isBeetlSqlContent) {
      return "";
    }

    char[] chars = text.toCharArray();
    int start = -1;
    boolean flag;//是否是有效字符
    for (int i = column; i >= 0; i--) {
      flag = false;
      for (char[] validChar : validChars) {
        int validCharLength = validChar.length;
        int from = Math.max((i - validCharLength), 0);
        char[] copyOfRange = Arrays.copyOfRange(chars, from, i);
        if (charsEqual(validChar, copyOfRange)) {
          start = from;
          flag = true;
          break;
        }
      }
      if (!flag) {
        break;
      }
    }

    if (start == -1) {
      return "";
    }

    return new String(Arrays.copyOfRange(chars, start, column));
  }

  private static boolean charsEqual(char[] chars1, char[] chars2) {

    if (chars1.length != chars2.length) {
      return false;
    }
    int min = chars1.length;
    for (int i = 0; i < min; i++) {
      if (chars1[i] != chars2[i]) {
        return false;
      }
    }
    return true;
  }

}
